home *** CD-ROM | disk | FTP | other *** search
/ MacWorld 1998 March / Macworld (1998-03) (Disk 1).dmg / Shareware World / Utilities / Text Processing / Alpha / Tcl / Menus / electricMenu.tcl < prev    next >
Encoding:
Text File  |  1997-12-03  |  9.9 KB  |  334 lines  |  [TEXT/ALFA]

  1. ## -*-Tcl-*-
  2.  # ###################################################################
  3.  #    Vince's    Additions -    an extension package for Alpha
  4.  # 
  5.  #    FILE: "electricMenu.tcl"
  6.  #                                      created: 8/3/96 {1:34:42 pm}    
  7.  #                                  last update: 3/12/97 {9:42:38 am}    
  8.  #    Author:    Vince Darley
  9.  #    E-mail:    <darley@fas.harvard.edu>
  10.  #      mail:    Division of    Applied    Sciences, Harvard University
  11.  #            Oxford Street, Cambridge MA    02138, USA
  12.  #       www:    <http://www.fas.harvard.edu/~darley/>
  13.  #    
  14.  #    Handles the electric menu.
  15.  #    
  16.  # ###################################################################
  17.  ##
  18.  
  19. alpha::menu electricMenu 1.2.2 "•280" in_menu {
  20.     alpha::package require elecCompletions 9.0b1
  21.     # so we don't use the standard proc to build this menu.
  22.     menu::buildProc elec "#"
  23. } maintainer {
  24.     "Vince Darley" darley@fas.harvard.edu <http://www.fas.harvard.edu/~darley/>
  25. } uninstall this-file help {file "ElecCompletions Help"}
  26.  
  27. lunion flagPrefs(Electrics) showElectricsInMenu putTemplatesInMainMenu \
  28.   showElectricKeysInMenu addTemplateManipulators 
  29.  
  30. namespace eval elec {}
  31.  
  32. proc electricMenu {} {
  33.     elec::rebuildElectricMenu
  34. }
  35.  
  36. eval lunion elec::MenuTemplates ""
  37. lunion elec::LicenseTemplates \
  38.     "none" "copyrightNotice" "allRightsReserved" \
  39.     "seeFileLicenseTerms" "gnuPublicLicense"
  40.  
  41. # register this proc to be called whenever the mode changes.
  42. hook::register changeMode elec::rebuildElectricMenu
  43. hook::register electricBindings elec::BindingsChanged
  44. # show electric completions in menu
  45. newPref flag showElectricsInMenu 1 global elec::clearAndBuildElectricMenu
  46. # show electric key bindings in menu
  47. newPref flag showElectricKeysInMenu 1 global elec::clearAndBuildElectricMenu
  48. # show electric key bindings in menu
  49. newPref flag addTemplateManipulators 0 global elec::clearAndBuildElectricMenu
  50. newPref flag putTemplatesInMainMenu 0 global elec::clearAndBuildElectricMenu
  51. proc elec::BindingsChanged {} {
  52.     global showElectricKeysInMenu
  53.     if $showElectricKeysInMenu {elec::clearAndBuildElectricMenu}
  54. }
  55.  
  56. proc elec::getMenuBindings {} {
  57.     global showElectricKeysInMenu elec::keyBindings
  58.     # get menu items which represent the current bindings
  59.     if $showElectricKeysInMenu {
  60.         return [menu::bindingsFromArray elec::keyBindings]
  61.     } else {
  62.         return ""
  63.     }
  64. }
  65.  
  66. ## 
  67.  # -------------------------------------------------------------------------
  68.  # 
  69.  # "elec::rebuildElectricMenu" --
  70.  # 
  71.  #  Reasonably clever procedure to construct a Template menu from the
  72.  #  ${mode}electrics array on the fly.  Works with 'ensemble' completions,
  73.  #  putting them in submenus (that's why the code is a little messy; I
  74.  #  couldn't dream up a neater method).
  75.  # -------------------------------------------------------------------------
  76.  ##
  77. proc elec::rebuildElectricMenu {args} {
  78.     set mmode [modeALike]
  79.     if [cache::exists elecMenu::elec-${mmode}] {
  80.         cache::read elecMenu::elec-${mmode}
  81.     } else {        
  82.         global ${mmode}electrics electricMenu showElectricsInMenu
  83.  
  84.         set m [list menu -n ${electricMenu} -m -p elec::MenuProc]
  85.         # make the menu of electrics if desired
  86.         if {$showElectricsInMenu && [array exists ${mmode}electrics]} {
  87.             set items [lsort [array names ${mmode}electrics]]
  88.             # remove all contractions
  89.             set items [lremove -all -glob $items "*'*"]
  90.             # remove something else (I've forgotten what!)
  91.             regsub -all { [^ ]*\*[^ ]*} " $items " { } items
  92.             set c [set items]
  93.             while {[regexp {\{(\w+) \w+\}} $c all pref]} {
  94.                 set c [string range $c [expr [string last "\{$pref " $c] +2] end]
  95.                 lappend got $pref
  96.             }
  97.             if [info exists got] {
  98.                 foreach pref $got {
  99.                     regsub "(\{${pref} \\w+\} )+" $items \
  100.                     "\{menu -n \"   ${pref}\" -m -p elec::MenuProc \{\\0\}\} " items
  101.                 }
  102.             }    
  103.         } else {
  104.             set items ""
  105.         }
  106.         # make the whole menu
  107.         set items [concat [elec::makeTemplatesMenu $mmode] $items "(-" \
  108.             [elec::getMenuBindings] [list "Add Electric Item"] ]
  109.         global addTemplateManipulators
  110.         if ${addTemplateManipulators} {
  111.             lappend items "Grab Selection" "Insert Old Selection" \
  112.                 "Insert In Lines"
  113.         }
  114.         lappend items "Clear Elec Menu Cache"
  115.         lappend m $items
  116.         cache::add elecMenu::elec-${mmode} variable m
  117.     }
  118.     eval $m
  119. }
  120.  
  121. proc elec::clearAndBuildElectricMenu {args} {
  122.     cache::deletePat elecMenu::elec-*
  123.     elec::rebuildElectricMenu
  124. }
  125.  
  126. proc elec::makeTemplatesMenu {mmode} {
  127.     # make the templates submenu
  128.     global ${mmode}Templates elec::MenuTemplates \
  129.         elec::LicenseTemplates menu::additions putTemplatesInMainMenu
  130.     set m ${elec::MenuTemplates}
  131.     if [info exists ${mmode}Templates] {
  132.         set m [concat $m [set ${mmode}Templates]]
  133.     }
  134.     set m [lsort $m]
  135.     eval lappend m "(-" [lsort [lremove ${elec::LicenseTemplates} "none"]]
  136.     if [info exists menu::additions(elec)] {
  137.         foreach i [set menu::additions(elec)] {
  138.             eval lappend m "(-" [lrange $i 2 end]
  139.         }
  140.     }
  141.     lappend m "(-" "addTemplateItem" "removeTemplateItem"
  142.     if $putTemplatesInMainMenu {
  143.         foreach i $m {
  144.             if {[lindex $i 0] == "menu"} {
  145.                 lappend ret $i
  146.             } else {
  147.                 lappend ret "[quote::Prettify $i] "
  148.             }
  149.         }
  150.         return $ret
  151.     } else {    
  152.         return [list "menu -n Templates -p elec::userTemplates [list $m]"]
  153.     }
  154.     
  155. }
  156.  
  157. proc elec::rebuildTemplatesMenu { {mmode ""} } {
  158.     if {$mmode == ""} {set mmode [modeALike]}
  159.     eval [lindex [elec::makeTemplatesMenu $mmode] 0]
  160. }
  161.  
  162. proc elec::userTemplates {menu item} {
  163.     set t [file::$item]    
  164.     if {$t != ""} {
  165.         elec::Insertion $t
  166.     }
  167. }
  168.  
  169. proc elec::MenuProc {menu item} {
  170.     switch $item {
  171.         "Next Stop Or Indent" {bind::IndentOrNextstop}
  172.         "Prev Stop" { ring::- }
  173.         "nth Stop" {ring::nth}
  174.         "Complete" {bind::Completion}
  175.         "Complete Or Tab" {bind::TabOrComplete}
  176.         "Expand" {bind::Expansion}
  177.         "Next Stop" {ring::+}
  178.         "Real Tab" {insertActualTab}
  179.         "Add Electric Item" {elec::AddItem}
  180.         "Grab Selection" {elec::GrabSelection}
  181.         "Insert Old Selection" {elec::InsertOldSelection}
  182.         "Insert In Lines" {elec::InsertInLines}
  183.         "Clear All Stops" {ring::clear}
  184.         "Clear Elec Menu Cache" {elec::clearAndBuildElectricMenu}
  185.         default {
  186.             if [regexp {(.*) $} $item "" item] {
  187.                 set item [join $item ""]
  188.                 elec::userTemplates $menu \
  189.                     [string tolower [string index $item 0]][string range $item 1 end]
  190.             } else {
  191.                 insertText $item
  192.                 bind::Completion
  193.             }
  194.         }
  195.     }
  196. }
  197.  
  198. proc elec::AddItem {} {
  199.     global mode
  200.     if {$mode == ""} { beep ; message "No mode set…" ; return }
  201.     global ${mode}electrics
  202.     set e [prompt "Enter the electric item for '$mode' mode:" ""]
  203.     if {$e == ""} {return}
  204.     set default [file::_getDefault "Do you want to start with this as the template?" \
  205.         [file::_varValue ${mode}electrics($e)]]
  206.     set value [getline "Enter the electric extension, using •prompt•, \\r \\\{, \\\} etc" $default]
  207.     if {$value != ""} {
  208.         if {[string length $value] > 210} {
  209.             alertnote "Alpha unfortunately truncates direct entry to about 200 characters, however you can add directly to arrdefs.tcl"
  210.         }
  211.         eval set ${mode}electrics($e) \"$value\"
  212.         addArrDef ${mode}electrics $e [set ${mode}electrics($e)]
  213.         elec::rebuildElectricMenu
  214.     }
  215. }
  216.  
  217. proc file::addTemplateItem {} {
  218.     global elec::MenuTemplates mode
  219.     global ${mode}Templates
  220.     set v elec::MenuTemplates
  221.     set v [expr {$mode != "" && [dialog::yesno \
  222.       "Is this item '$mode' mode-specific (otherwise I'll make it global)?"] \
  223.       ? "${mode}Templates" : "elec::MenuTemplates"}]
  224.     set e [join [prompt "Enter the new template menu item name:" ""] ""]
  225.     if {$e == ""} {return}
  226.     set e [string tolower [string index $e 0]][string range $e 1 end]
  227.     set default [file::_getDefault "Do you want to start with this as the template?"]
  228.     set t "\r"
  229.     append t "proc file::${e} \{\} \{\r"
  230.     append t "\t# You must fill this in\r"
  231.     append t $default
  232.     append t "\r\r\telec::Insertion \$t\r\}\r"
  233.     addUserLine $t
  234.     lappend $v $e
  235.     lappend modifiedVars $v
  236.     elec::rebuildTemplatesMenu
  237.     regsub -all "\r" $default ";" default
  238.     append default { elec::Insertion $t}
  239.     proc file::$e {} $default
  240.     elec::clearAndBuildElectricMenu
  241.     if {[dialog::yesno "I've added a template for the procedure to your 'prefs.tcl'. Do you want to edit it now?"]} {
  242.         global::editPrefsFile
  243.         goto [maxPos]
  244.     }
  245.     return ""
  246. }
  247.  
  248. proc file::removeTemplateItem {} {
  249.     global elec::MenuTemplates mode
  250.     global ${mode}Templates
  251.     global modifiedVars
  252.     set tlist ${elec::MenuTemplates}
  253.     catch {set tlist [concat $tlist [set ${mode}Templates]]}
  254.     set l [listpick -p "Which template shall I permanently remove?" \
  255.       [lsort $tlist]]
  256.     if {[set i [lsearch ${elec::MenuTemplates} $l]] != -1} {
  257.         set elec::MenuTemplates [lreplace ${elec::MenuTemplates} $i $i]
  258.         lappend modifiedVars elec::MenuTemplates
  259.     } else {
  260.         set i [lsearch [set ${mode}Templates] $l]
  261.         set ${mode}Templates [lreplace [set ${mode}Templates] $i $i]
  262.         lappend modifiedVars ${mode}Templates
  263.     }
  264.     elec::rebuildTemplatesMenu
  265.     elec::clearAndBuildElectricMenu
  266.     global::editPrefsFile
  267.     set pat {\rproc[ \t]+file::}
  268.     append pat $l
  269.     append pat {[ \t]+\{[ \t]*\}[ \t]\{(\r[^\}].*)*\r\}\r}
  270.     while 1 {
  271.         set fpos [search -f 1 -r 1 -n $pat 0]
  272.         if {[string compare $fpos ""] == 0} {
  273.             break
  274.         }
  275.         deleteText [lindex $fpos 0] [lindex $fpos 1]
  276.     }
  277.     while 1 {
  278.         set fpos [search -f 1 -r 1 -n {^\r\r} 0]
  279.         if {[string compare $fpos ""] == 0} {
  280.             break
  281.         }
  282.         replaceText [lindex $fpos 0] [lindex $fpos 1] "\r"
  283.     }
  284.     save
  285.     return ""
  286. }
  287.  
  288.  
  289. # procedures below get added to the menu if you set the 'poweruser' flag
  290. # in "elecBindings.tcl".  They make it easy to create large template 
  291. # procedures 
  292. proc elec::GrabSelection {} {
  293.     global __elec::grabbed
  294.     set __elec::grabbed [getSelect]
  295. }
  296.  
  297. proc elec::InsertOldSelection {} {
  298.     global __elec::grabbed
  299.     insertText [quote::Insert [set __elec::grabbed]]
  300. }
  301.  
  302. proc elec::InsertInLines {} {
  303.     global __elec::grabbed
  304.     insertText [elec::_MakeIntoInsertion ${__elec::grabbed}]
  305. }
  306.  
  307. proc elec::_MakeIntoInsertion {t {var "t"}} {
  308.     if {$t == ""} { return $t }
  309.     regsub -all "\n" $t "\r" t
  310.     while 1 {
  311.         set ret [string first "\r" $t]
  312.         if { $ret == -1 } { set ret [string length $t] }
  313.         append b [string range $t 0 $ret]
  314.         if {[string length $b] > 20} {
  315.             while 1 {
  316.                 append a "\tappend $var \"[quote::Insert [string range $b 0 59]]\"\r"
  317.                 if {[set b [string range $b 60 end]] == ""} {
  318.                     break
  319.                 }
  320.             }
  321.         }
  322.         set t [string range $t [incr ret] end]
  323.         if {[string length $t] == 0} { 
  324.             if {$b != ""} {
  325.                 append a "\tappend $var \"$b\"\r"
  326.             }
  327.             break 
  328.         }
  329.     }
  330.     return $a
  331. }
  332.  
  333.  
  334.